<template>
  <el-container style="height: calc(100vh - 65px)">
    <el-aside>
      <div class="components-nav">
        <span @click="libSelect = 0">组件库</span>
      </div>
      <div>
        <div class="components" v-for="(group, i) in baseComponents" :key="i">
          <p>{{ group.name }}</p>
          <ul>
            <draggable class="drag" :list="group.components" item-key="id" :sort="false"
                       :group="{ name: 'form', pull: 'clone', put: false}"
                        @start="isStart = true" @end="isStart = false" :clone="clone">
              <template #item="{element}">
                <li>
                  <!-- <icon :name="element.icon" style="width: 12px; height: 12px"></icon> -->
                  <SvgIcon :name="element.icon" style="width: 12px; height: 12px;margin: 0 12px;" />
                  <span>{{ element.title }}</span>
                </li>
              </template>
            </draggable>
          </ul>
        </div>
      </div>
    </el-aside>

    <el-main class="layout-main">
      <div class="tool-nav">
        <div>
          <el-tooltip class="item" effect="dark" content="移动端" placement="bottom-start">
            <!-- <icon :name="`el-icon-cellphone`"></icon> -->
            <el-icon style="margin-right: 10px" @click="showMobile = true" :color="showMobile ? '#7a7a7a' : ''"><Cellphone /></el-icon>
          </el-tooltip>
          <el-tooltip class="item" effect="dark" content="PC端" placement="bottom-start">
            <!-- <icon :name="`el-icon-monitor ${!showMobile ? 'select' : ''}`"></icon> -->
            <el-icon @click="showMobile = false" :color="!showMobile ? '#7a7a7a' : ''"><Monitor /></el-icon>
          </el-tooltip>
        </div>
        <div>
          <el-tooltip class="item" effect="dark" content="预览表单" placement="bottom-start">
            <div style="display: flex; align-items: center; cursor: pointer" @click="viewForms">
              <!-- <icon name="el-icon-view"></icon> -->
              <el-icon style="margin: 0 10px" color="#7a7a7a"><View /></el-icon>
              <span style="font-size: 13px; color: #666666">预览表单</span>
            </div>
          </el-tooltip>
        </div>
      </div>
      <div class="work-form"  @click="release">
        <div :class="{ mobile: showMobile, pc: !showMobile }">
          <div :class="{ bd: showMobile }">
            <div :class="{ 'form-content': showMobile }">
              <div class="form">
                <div class="tip" v-show="forms.length === 0 && !isStart">
                  👈 请在左侧选择控件并拖至此处
                </div>
                <draggable class="drag-from" item-key="id" v-model="forms" v-bind="dragProps"
                           :component-data="{tag: 'div', type: 'transition-group'}"
                           @start="drag = true; selectFormItem = null" @end="drag = false">
                  <template #item="{element, index}">
                    <div class="form-item" @click.stop="selectItem(element)" :style="getSelectedClass(element)">
                      <div class="form-header">
                        <p><span v-if="element.props.required">*</span>{{ element.title }}</p>
                        <div class="option">
                          <!--<icon name="el-icon-copy-document" @click="copy"></icon>-->
                           <!-- <icon name="el-icon-close"></icon> -->
                           <el-icon @click="del(index)" :size="13" style="margin:5px"><Close /></el-icon>
                        </div>
                        <form-design-render :config="element" />
                      </div>
                    </div>
                  </template>
                </draggable>
              </div>
            </div>
          </div>
        </div>
      </div>
    </el-main>

    <el-aside class="layout-param">
      <div class="tool-nav-r" v-if="selectFormItem">
        <!-- <icon :key="selectFormItem.icon" :name="selectFormItem.icon" style="margin-right: 5px; font-size: medium"></icon> -->
        <SvgIcon :name="selectFormItem.icon" style="margin-top:2px;margin-right:5px" />
        <span>{{ selectFormItem.title }}</span>
      </div>
      <div v-if="!selectFormItem || forms.length === 0">
        <div class="title tool-nav-r">
          <!-- <icon name="el-icon-tickets"></icon> -->
          <el-icon style="margin-right: 5px"><Tickets /></el-icon>
          表单联动
        </div>
        <form-config/>
      </div>
      <div style="text-align:left; padding: 10px" v-else>
        <form-component-config :key="selectFormItem.id"/>
      </div>
    </el-aside>
    <w-dialog clickClose width="750px" :border="false" @ok="doPrint" title="打印预览" okText="打印" v-model="viewPrintVisible">
      <div id="print" v-if="viewPrintVisible" v-html="printContent"></div>
    </w-dialog>
    <w-dialog clickClose width="700px" :showFooter="false" :border="false" title="表单预览" v-model="viewFormVisible">
      <template #title>
        <div>
          <span>表单预览</span>
          <el-radio-group style="margin: 0 30px" v-model="forViewMode">
            <el-radio label="PC">电脑端</el-radio>
            <el-radio label="MOBILE">手机端（需保存才生效）</el-radio>
          </el-radio-group>
          <el-popover placement="bottom" title="手机扫码预览表单" width="195" trigger="click">
            <qrcode-vue :value="qrCode" :size="170" level="H"/>
            <template #reference>
              <el-link type="primary" style="margin-top: -8px;">扫码预览</el-link>
            </template>
          </el-popover>
          <el-link v-if="customPrint" style="margin-left: 30px" type="primary" @click="showPrint">打印预览</el-link>
        </div>
      </template>
      <div v-show="forViewMode === 'PC'">
        <form-render ref="form" v-model="formData" :forms="formsTemp" mode="PC" :config="formConfigTemp"/>
      </div>
      <div v-if="forViewMode === 'MOBILE'">
        <div style="display: flex; justify-content: center">
          <iframe width="400px" height="700px" frameborder="0" :src="`/#/workflow?code=${route.query.code}&mobilePreview=true`"></iframe>
        </div>
      </div>
    </w-dialog>
  </el-container>
</template>

<script>
import { computed, reactive, toRefs, nextTick } from 'vue'
import { useRoute } from 'vue-router'
import QrcodeVue from 'qrcode.vue'
import draggable from 'vuedraggable'
import { ElMessageBox } from 'element-plus'
import Editor from '/@/components/editor/index.vue';
import FormRender from '/@/views/setting/workflow/components/FormRender.vue'
import FormDesignRender from '/@/views/setting/workflow/common/FormDesignRender.vue'
import FormComponentConfig from '/@/views/setting/workflow/components/FormComponentConfig.vue'
import FormConfig from '/@/views/setting/workflow/config/FormConfig.vue'
import { baseComponents } from '/@/views/setting/workflow/config/ComponentsConfigExport'
import { deepCopy, Print, bindVar, getVal } from '/@/utils/utils'
import { useWorkFlowConfig } from '/@/stores/workFlow'
import { storeToRefs } from 'pinia'
import { Tickets, View, Cellphone, Monitor, Close } from '@element-plus/icons-vue'

const varExp = /\${\w+}/gi
export default {
    name: 'FormDesign',
    components: {
        draggable,
        QrcodeVue,
        Editor,
        FormRender,
        FormDesignRender,
        FormComponentConfig,
        FormConfig,
        Tickets,
        View,
        Cellphone,
        Monitor,
        Close
    },
    setup() {
        const storesWorkFlowConfig = useWorkFlowConfig()
        const workFlowConfig = storeToRefs(storesWorkFlowConfig)
        const route = useRoute()
        const state = reactive({
            formConfigTemp: {},
            formsTemp:{},
            formData: {},
            libSelect: 0,
            printContent: '',
            forViewMode: 'PC',
            viewFormVisible: false,
            viewPrintVisible: false,
            isStart: false,
            showMobile: true,
            baseComponents,
            select: null,
            drag: false,
            qrcode: null,
            dragProps:{
                animation: 300,
                group: "form",
                disabled: false,
                sort: true,
                ghostClass: "choose",
            },
            design: {},
            selectForm: [],
            form: {}
        })
        const formConfig = computed(() => {
            return workFlowConfig.design.value.formConfig
        })
        const qrCode = computed(() => {
            return window.location.href + '&mobilePreview=true'
        })
        const formatFormData = computed(() => {
            let val = {}
            getVal(state.formData, forms.value, val)
            return val
        })
        const forms = computed({
            get: () => {
                state.design = workFlowConfig.design.value
                return workFlowConfig.design.value.formItems
            },
            set: val => {
                state.design.formItems = val
                storesWorkFlowConfig.loadForm(state.design)
            }
        })
        const customPrint = computed(() => {
            return workFlowConfig.design.value.settings.customPrint
        })
        const printTemplate = computed(() => {
            return workFlowConfig.design.value.settings.printTemplate
        })
        const selectFormItem = computed({
            get: () => {
                state.selectForm = workFlowConfig.selectFormItem.value
                return workFlowConfig.selectFormItem.value
            },
            set: val => {
                storesWorkFlowConfig.setSelectForm(val)
            }
        })
        const nodeMap = computed(() => {
            return workFlowConfig.nodeMap.value
        })
        const release = () => {
            selectFormItem.value = null
        }
        const copy = (node, index) => {
            state.form.splice(index + 1, 0, Object.assign({}, node))
        }
        const getId = () => {
            return (
                'field' +
                (Math.floor(Math.random() * (99999 - 10000)) + 10000).toString() +
                new Date().getTime().toString().substring(5)
            )
        }
        const showPrint = () => {
            state.viewPrintVisible = true
            state.printContent = printTemplate.value.replace(varExp, (mc) => {
                return formatFormData.value[mc.substring(2, mc.length - 1).trim()] || mc
            })
            nextTick(() => {
                bindVar(printTemplate.value, formatFormData.value, 'print')
            })
        }
        const del = (index) => {
            ElMessageBox.confirm(
                '删除组件将会连带删除包含该组件的条件以及相关设置，是否继续?',
                '提示',
                {
                    confirmButtonText: '确 定',
                    cancelButtonText: '取 消',
                    type: 'warning',
                }
            ).then(() => {
              console.log('1'+selectFormItem.value)
              console.log('2'+forms.value)
                if (forms.value[index].name === 'SpanLayout') {
                    //删除的是分栏则遍历删除分栏内所有子组件
                    forms.value[index].props.items.forEach((item) => {
                        removeFormItemAbout(item)
                    })
                    forms.value[index].props.items.length = 0
                } else {
                    removeFormItemAbout(forms.value[index])
                }
                forms.value.splice(index, 1)
            })
        }
        const removeFormItemAbout = async (item) =>{
            nodeMap.value.forEach((node) => {
                //搜寻条件，进行移除
                if (node.type === 'CONDITION') {
                    node.props.groups.forEach((group) => {
                        let i = group.cids.remove(item.id)
                        if (i > -1) {
                            //从子条件移除
                            group.conditions.splice(i, 1)
                        }
                    })
                }
                //搜寻权限，进行移除
                if (
                    node.type === 'ROOT' ||
                    node.type === 'APPROVAL' ||
                    node.type === 'CC'
                ) {
                    const index = node.props.formPerms.findIndex((value) => value[id] === item.id)
                    if (index > -1) {
                      node.props.formPerms.splice(index, 1)
                    }
                    if (node.props.formUser === item.id) {
                        node.props.formUser = ''
                    }
                }
            })
        }
        const clone = obj => {
            const clone = JSON.parse(JSON.stringify(obj))
            clone.id = getId()
            return clone
        }
        const viewForms = () => {
            state.forViewMode = 'PC'
            state.viewFormVisible = true
            state.formData = {}
            state.formsTemp = deepCopy(forms.value)
            state.formConfigTemp = deepCopy(formConfig.value)
        }
        const selectItem = (cp) => {
            selectFormItem.value = cp
        }
        const getSelectedClass = cp => {
            return selectFormItem.value && selectFormItem.value.id === cp.id ?'border-left: 4px solid #409eff' : ''
        }
        const validateItem = (err, titleSet, item) => {
            if (titleSet.has(item.title) && item.name !== 'SpanLayout') {
                err.push(`表单 ${item.title} 名称重复`)
            }
            titleSet.add(item.title)
            if (item.name === 'SelectInput' || item.name === 'MultipleSelect') {
                if (item.props.options.length === 0) {
                    err.push(`${item.title} 未设置选项`)
                }
            } else if (item.name === 'TableList') {
                if (item.props.columns.length === 0) {
                    err.push(`明细表 ${item.title} 内未添加组件`)
                }
            } else if (item.name === 'SpanLayout') {
                if (item.props.items.length === 0) {
                    err.push('分栏内未添加组件')
                } else {
                    item.props.items.forEach((sub) =>
                        validateItem(err, titleSet, sub)
                    )
                }
            }
        }
        const validate = () => {
            let err = []
            if (forms.value.length > 0) {
                let titleSet = new Set()
                forms.value.forEach((item) => {
                    //主要校验表格及分栏/选择器/表单名称/是否设置
                    validateItem(err, titleSet, item)
                })
            } else {
                err.push('表单为空，请添加组件')
            }
            return err
        }
        const doPrint = () => {
            Print(document.getElementById('print'))
        }
        return {
            ...toRefs(state),
            formConfig,
            forms,
            qrCode,
            customPrint,
            printTemplate,
            formatFormData,
            selectFormItem,
            nodeMap,
            release,
            copy,
            getId,
            showPrint,
            del,
            clone,
            viewForms,
            selectItem,
            getSelectedClass,
            validate,
            doPrint,
            route
        }
    }
}
</script>

<style lang="scss" scoped>
.choose {
  border: 1px dashed var(--el-color-primary) !important;
}

iframe {
  border-radius: 8px;
  box-shadow: 0 0 10px #dcdbdb;
}

.process-form {
   :deep(.el-form-item__label) {
    padding: 0 0;
  }
}

.components-nav {
  box-sizing: content-box;
  display: flex;
  align-items: center;
  margin: 12px 12px 0;
  height: 28px;
  box-shadow: 0 2px 4px 0 rgba(17, 31, 44, 0.04);
  border: 1px solid #ecedef;
  border-radius: 16px;
  background-color: #fff;

  .selected {
    color: var(--el-color-primary);
  }

  .border {
    border-left: 1px solid #f5f6f6;
    border-right: 1px solid #f5f6f6;
  }

  span {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100%;
    font-size: 12px;
    color: rgba(17, 31, 44, 0.72);
    cursor: pointer;

    &:hover {
      color: var(--el-color-primary);
    }
  }
}

.components {
  overflow-x: hidden;
  overflow-y: scroll;
  //margin-top: 20px;
  //padding: 0 20px;
  font-size: 12px;
  width: 100%;
  color: rgba(17, 31, 44, 0.85);

  & > p {
    padding: 12px 20px;
  }

  .drag {
    margin-left: 20px;
    display: flex;
    flex-wrap: wrap;
    align-items: center;

    li {
      text-align: center;
      display: flex;
      align-items: center;
      width: 124px;
      height: 38px;
      margin-bottom: 12px;
      border: 1px solid transparent;
      border-radius: 8px;
      cursor: grab;
      background-color: #fff;

      &:hover {
        border: 1px solid var(--el-color-primary);
        color: var(--el-color-primary);
      }

      :deep(.icon) {
        margin: 0 12px;
      }
    }

    li:nth-child(odd) {
      margin-right: 8px;
    }
  }
}

 :deep(.el-main) {
  padding: 0;
}

.layout-main {
  background-color: #feffff;
  min-width: unset;
  .tool-nav {
    font-size: medium;
    padding: 8px 20px;
    background: #fafafb;
    border-bottom: 1px solid #ebecee;

    div:first-child {
      display: inline-block;
      text-align: left;

      :deep(.icon) {
        margin-right: 10px
      }
    }

    div:last-child {
      float: right;

      :deep(.icon) {
        margin-left: 10px
      }
    }

    :deep(.icon) {
      color: #7a7a7a;
      cursor: pointer;

      &:hover {
        color: #4b4b4b;
      }
    }
  }

  .work-form {
    margin: 0 auto;
    height: calc(100% - 38px);
    overflow-y: auto;
    background: rgb(245, 246, 246);
    border-left: 1px solid rgb(235, 236, 238);
    border-right: 1px solid rgb(235, 236, 238);

    .pc {
      margin-top: 4%;

      .drag-from {
        height: calc(100vh - 190px);
        background-color: rgb(245, 246, 246);

        .form-item, li {
          cursor: grab;
          background: #ffffff;
          padding: 10px;
          border: 1px solid #ebecee;
          margin: 5px 0;
        }
      }
    }

    .mobile {
      margin-left: auto;
      margin-right: auto;
      width: 360px;
      max-height: 640px;
      margin-top: 4%;
      border-radius: 24px;
      box-shadow: 0 8px 40px 0 rgba(17, 31, 44, 0.12);

      .bd {
        border: 1px solid rgba(17, 31, 44, 0.08);
        border-radius: 24px;
        padding: 10px 10px;
        background-color: #ffffff;

        .form-content {
          padding: 3px 2px;
          border-radius: 14px;
          background-color: #f2f4f5;

          .drag-from {
            width: 100%;
            height: calc(100vh - 190px);
            min-height: 200px;
            max-height: 600px;
          }

          .form {
            overflow-y: auto;
            width: 100%;
            display: inline-block;
            max-height: 640px;

            .form-item, li {
              border: 1px solid #ffffff;
              list-style: none;
              background: #ffffff;
              padding: 10px;
              margin: 5px 0;
              cursor: grab;
            }
          }
        }
      }
    }

    .tip {
      //float: left;
      margin: 0 auto;
      width: 65%;
      max-width: 400px;
      padding: 35px 20px;
      border-radius: 10px;
      border: 1px dashed rgba(25, 31, 37, 0.12);
      margin-top: 50px;
      text-align: center;
      font-size: 14px;
      color: rgb(122, 122, 122);
      z-index: 9999;

      &:hover {
        border: 1px dashed var(--el-color-primary);
      }
    }
  }

}

.layout-param {
  text-align: center;
  font-size: 14px;
  color: rgb(122, 122, 122);

  .tool-nav-r {
    display: flex;
    text-align: left;
    font-size: small;
    border-left: 1px solid #ebecee;
    padding: 9px 20px;
    background: #fafafb;
    border-bottom: 1px solid #ebecee;
  }
  .title{
    font-style: normal;
    display: flex;
    align-items: center;
    .icon{
      margin-right: 10px;
    }
  }
}

.flip-list-move {
  transition: transform 0.5s;
}

.no-move {
  transition: transform 0s;
}

.select {
  color: #4b4b4b !important;
}

.form-header {
  font-size: small;
  color: #818181;
  text-align: left;
  position: relative;
  background-color: #fff;

  p {
    position: relative;
    margin: 0 0 10px 0;

    span {
      position: absolute;
      left: -8px;
      top: 3px;
      color: rgb(217, 0, 19);
    }
  }

  .option {
    position: absolute;
    top: -10px;
    right: -10px;

    :deep(.icon) {
      font-size: large;
      cursor: pointer;
      color: #8c8c8c;
      padding: 5px;

      &:hover {
        color: #f56c6c;
      }
    }
  }
}

::-webkit-scrollbar {
  width: 4px;
  height: 4px;
  background-color: #f8f8f8;
}

::-webkit-scrollbar-thumb {
  border-radius: 16px;
  background-color: #e8e8e8;
}
</style>